import Axios from 'axios'
import createAxiosError from 'axios/lib/core/createError'
import LeUtils from "./le-utils";
import LeStorage from "./le-storage"

Axios.defaults.withCredentials = true;
Axios.defaults.timeout = 0;
Axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
Axios.defaults.loadingService=null
let token = document.head.querySelector('meta[name="csrf-token"]');
//laravel csrf-token
if (token) {
    Axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
}


async function leAxiosInterceptorsResponseSuccess(response, quiet) {

    let res_data = LeUtils.valueGet(response, 'data', null);
    let axiosError = createAxiosError(
        '接口返回错误',
        response.config,
        null,
        response.request,
        response,
    );
    if (!res_data) {

        return leAxiosInterceptorsResponseError(axiosError, quiet);
    }

    let res_code = LeUtils.valueGet(res_data, 'code', 0);
    res_code = parseInt(res_code)
    switch (res_code) {
        case 20401:
            if (true !== quiet) {
                let vueApp = LeUtils.valueGet(window, 'VueApp', null);
                if (vueApp) {
                    vueApp.$emit('authMenu.openAuthDialog', 'login')
                }
            }
            return leAxiosInterceptorsResponseError(axiosError, quiet);
            break;
        case 20403:
            return leAxiosInterceptorsResponseError(axiosError, quiet);
            break;
        case 20301:
            let redirectUrl = LeUtils.valueGet(res_data, 'redirect_url', LeUtils.valueGet(res_data, 'data.redirect_url', LeUtils.valueGet(res_data, 'data', '')));
            if (redirectUrl && LeUtils.typeIs('string',redirectUrl)) {
                window.location.href = redirectUrl;
                return null;
            }
            break;
        case 20302:
            let forward_url = LeUtils.valueGet(res_data, 'data.forward_url', ''),
                forward_headers = LeUtils.valueGet(res_data, 'data.forward_headers', {}),
                forward_params = LeUtils.valueGet(res_data, 'data.forward_params', {}),
                forward_method = LeUtils.valueGet(res_data, 'data.forward_method', 'POST'),
                forward_return_api = LeUtils.valueGet(res_data, 'data.forward_return_api', ''),
                forward_return_method = LeUtils.valueGet(res_data, 'data.forward_return_method', ''),
                originalHeaders = LeUtils.valueGet(response, 'config.headers', {}), // 第一次请求后端的参数数据
                originalParams = LeUtils.valueGet(response, 'config.params', {}), // 第一次请求后端的参数数据
                originalData = LeUtils.valueGet(response, 'config.data', {}); // 第一次请求后端的参数数据

            if (LeUtils.typeIs('string', originalParams)) {
                try {
                    originalParams = JSON.parse(originalParams)
                } catch (e) {
                    originalParams = {}
                }
            }
            if (LeUtils.typeIs('string', originalData)) {
                try {
                    originalData = JSON.parse(originalData)
                } catch (e) {
                    originalData = {}
                }
            }
            if (!forward_url || !forward_return_api) {
                return leAxiosInterceptorsResponseError(createAxiosError(
                    '接口返回错误',
                    response.config,
                    null,
                    response.request,
                    response,
                ), quiet);
            }

            let forward_use_params = true;

            if (['PUT', 'POST', 'PATCH'].includes(forward_method.toUpperCase())) {
                forward_use_params = false;
            }

            res_data = await Axios.request({
                url: forward_url,
                method: forward_method,
                params: forward_use_params ? forward_params : null,
                data: forward_use_params ? null : forward_params,
                headers: forward_headers,
            });

            if (['PUT', 'POST', 'PATCH'].includes(forward_return_method.toUpperCase())) {
                originalData = Object.assign({}, originalData, {forward_return_result: res_data});
            } else {
                originalParams = Object.assign({}, originalParams, {forward_return_result: res_data});
            }
            res_data = await Axios.request({
                url: forward_return_api,
                method: forward_return_method,
                params: originalParams,
                data: originalData,
                headers: originalHeaders,
            });
            break;
    }

    let res_status = LeUtils.valueGet(res_data, 'status', false);

    if (true !== res_status) {
        axiosError.message = LeUtils.valueGet(res_data, 'message', '操作失败');
        return leAxiosInterceptorsResponseError(axiosError, quiet);
    }
    return res_data;
}

function leAxiosInterceptorsResponseError(error, quiet) {

    quiet = quiet || false
    let responseMsg = LeUtils.valueGet(error, 'response.data.message');
    let msg = responseMsg || error.message;

    let errors = LeUtils.valueGet(error, 'response.data.errors', {})

    try{
        error.message = msg;
    }catch (e) {

    }


    if('CSRF token mismatch.' == msg){
        msg = '页面已过期，请刷新重试';
    }else if('Unauthenticated.' == msg){
        msg = '权限不足!'
    }

    if(LeUtils.isEmpty(errors)){
        errors = msg
    }else {
        errors = LeUtils.joinToString(errors, "<br>")
    }

    msg = '系统提示';
    //console.log(quiet)

    if (true !== quiet) {
        Axios.messageHandle(errors,'error')
    }

    return Promise.reject(error);
}

async function leAxiosInterceptorsRequestBefore(config, quiet) {

    if (!LeUtils.valueGet(window,'_LaravelExtendAssentsNotUseAuthToken',false)){
        let tokenId = LeStorage.getAuthToken('id', '');

        if(tokenId){
            config.headers['Authorization'] = 'Bearer ' + tokenId;
        }


        //config.headers['ClientPlatform'] = '';
        let clientSource = LeStorage.getClientSource()
        if(clientSource){
            config.headers['ClientSource'] = clientSource;
        }
    }


    return config;
}
function leAxiosInterceptorsRequestError(error, quiet) {
    if (true !== quiet) {
        Axios.messageHandle(error.message,'error')
    }
    return Promise.reject(error);
}

function tryCloseLoading(_loading){
    if(!_loading){
        return;
    }
    try {
        _loading.close();
    }catch (e) {

    }
}

function assignAxiosInterceptors(_axios,quiet){
    quiet = !!quiet;
    _axios.interceptors.response.use(function (response) {
        tryCloseLoading(LeUtils.valueGet(response,'config.loadingService'))
        return leAxiosInterceptorsResponseSuccess(response, quiet)

    }, function (error) {
        tryCloseLoading(LeUtils.valueGet(error,'config.loadingService'))
        return leAxiosInterceptorsResponseError(error, quiet)
    });
    _axios.interceptors.request.use(function (config) {
        // 在发送请求之前做些什么
        return leAxiosInterceptorsRequestBefore(config,quiet);
    }, function (error) {
        // 对请求错误做些什么

        tryCloseLoading(LeUtils.valueGet(error,'config.loadingService'))
        return leAxiosInterceptorsRequestError(error,quiet)
    });
}

assignAxiosInterceptors(Axios,false);
/*

Axios.interceptors.response.use(function (response) {
    console.log('leAxiosInterceptorsResponseSuccess')
    console.log(response.config)
    return leAxiosInterceptorsResponseSuccess(response, false)

}, function (error) {
    console.log('leAxiosInterceptorsResponseError')
    console.log(error.config)
    return leAxiosInterceptorsResponseError(error, false)
});
Axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    return leAxiosInterceptorsRequestBefore(config,false);
}, function (error) {
    // 对请求错误做些什么
    console.log('leAxiosInterceptorsRequestError')
    console.log(error.config)
    return leAxiosInterceptorsRequestError(error,false)
});
*/

Axios.useLoading = function (loadingService){
    let _this = Axios.create(this.defaults);
    _this.defaults.loadingService = loadingService;
    assignAxiosInterceptors(_this,false)
    return _this;
}
Axios.quiet = function () {

    let _this = Axios.create(this.defaults);
    assignAxiosInterceptors(_this,true)

    return _this
}
Axios.org = function () {
    return Axios.create()
}
Axios.messageHandle = function (msg,type){
    if(LeUtils.typeIs('function',window.LeExtendMessageHandle)){
        return window.LeExtendMessageHandle(msg,type)
    }
    alert(msg);
}

export default Axios
export {
    leAxiosInterceptorsRequestError,
    leAxiosInterceptorsResponseError
}
